GLSL 语法简介

您所在的位置:网站首页 hypermesh定义材料的MAT4中K CP RHO定义 GLSL 语法简介

GLSL 语法简介

2024-07-12 08:09| 来源: 网络整理| 查看: 265

GLSL 语法简介 ​

GLSL 是为图形计算量身定制的用于编写着色器的语言,它包含一些针对向量和矩阵操作的特性,使渲染管线具有可编程性。本章主要介绍在编写 Shader 时常用的一些语法,包括以下几个方面:

变量语句限定符预处理宏定义变量 ​变量及变量类型 ​变量类型说明Cocos Shader 中的默认值Cocos Shader 中的可选项bool布尔型标量数据类型false无int/ivec2/ivec3/ivec4包含 1/2/3/4 个整型向量0/[0, 0]/[0, 0, 0]/[0, 0, 0, 0]无float/vec2/vec3/vec4包含 1,2,3,4 个浮点型向量0/[0, 0]/[0, 0, 0]/[0, 0, 0, 0]无sampler2D表示 2D 纹理defaultblack、grey、white、normal、defaultsamplerCube表示立方体纹理default-cubeblack-cube、white-cube、default-cubemat[2..3]表示 2x2 和 3x3 的矩阵不可用mat4表示 4x4 的矩阵[1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]标量 ​

构造标量的方式和 C 语言一致:

glslfloat floatValue = 1.0; bool booleanValue = false;向量 ​

构造向量时的规则如下:

若向向量构造器提供了一个标量,则向量的所有值都会设定为该标量值若提供多个标量值或向量,则从左到右使用提供的值赋值。前提是标量或向量的数量之和要等于向量构造器的数量glslvec4 myVec4 = vec4(1.0); // myVec4 = {1.0, 1.0, 1.0, 1.0} vec2 myVec2 = vec2(0.5, 0.5); // myVec2 = {0.5, 0.5} vec4 newVec4 = vec4(1.0, 1.0, myVec2);// newVec4 = {1.0, 1.0, 0.5, 0.5}

向量可以通过 r, g, b, a 或 x, y, z, w 进行访问,也可以同时访问多个角标:

glslvec4 myVec4_0 = vec4(1.0); // myVec4_0 = { 1.0, 1.0, 1.0, 1.0 } vec4 myVec4 = vec4(1.0, 2.0, 3.0, 4.0); // myVec4 = { 1.0, 2.0, 3.0, 4.0 } float x = myVec4.x; // x = 1.0; vec3 myVec3_0 = myVec4.xyz; // myVec3_0 = { 1.0, 2.0, 3.0 } vec3 myVec3_1 = myVec4.rgb; // myVec3_1 = { 1.0, 2.0, 3.0 } vec3 myVec3_2 = myVec4.zyx; // myVec3_2 = { 3.0, 2.0, 1.0 } vec3 myVec3_3 = myVec4.xxx; // myVec3_3 = { 1.0, 1.0, 1.0 }矩阵 ​

在 GLSL 内可构造 mat[2..4] 来表示 2 阶到 4 阶的矩阵。

矩阵构造有如下的规则:

若只为矩阵构造器提供了一个标量,则该值会构造矩阵对角线上的值矩阵可以由多个向量构造矩阵可以由单个标量从左到右进行构造glsl mat4 marixt4x4 = mat4(1.0); // marixt4x4 = { 1.0, 0.0, 0.0, 0.0, // 0.0, 1.0, 0.0, 0.0 // 0.0, 0.0, 1.0, 0.0 // 0.0, 0.0, 0.0, 1.0 } vec2 col1 = vec2(1.0, 0.0); vec2 col2 = vec2(1.0, 0.0); mat2 matrix2x2 = mat2(coll1, col2); // GLSL 是列矩阵存储,因此构造时,构造器会按照列顺序进行填充 mat3 matrix3x3 = mat3(0.0, 0.0, 0.0, // 第一列 0.0, 0.0, 0.0, // 第二列 0.0, 0.0, 0.0); // 第三列

注意:为避免 implicit padding,引擎规定若要使用 Uniform 限定符的矩阵,必须是 4 阶矩阵,2 阶和 3 阶的矩阵不可作为 Uniform 变量。

矩阵的访问:

矩阵可以通过索引访问不同的列:

glslmat2 matrix2x2 = mat2(0.0, 0.0, 0.0, 0.0); vec4 myVec4 = vec4(matrix2x2[0], matrix2x2[1]); vec2 myVec2 = matrix2x2[0]; // 访问第一列的第一个元素 float value = matrix2x2[0][0]; matrix2x2[1][1] = 2.0;结构体 ​

结构体的形成和 C 语言类似,可由不同数据类型聚合而成:

cstruct myStruct { vec4 position; vec4 color; vec2 uv; };

构造结构体的代码示例如下:

glslmyStruct structVar = myStruct(vec4(0.0, 0.0,0.0,0.0), vec4(1.0, 1.0, 1.0, 1.0), vec2(0.5, 0.5));

结构体支持赋值(=)和比较(==,!=)运算符,但要求两个结构体拥有相同的类型且组件分量(component-wise)都必须相同。

数组 ​

数组的用法和 C 语言类似,规则如下:

数组必须声明长度数组不能在声明的同时初始化数组必须由常量表达式初始化数组不能用 const 修饰不支持多维数组

数组声明和初始化的代码示例如下:

glslfloat array[4]; for(int i =0; i = 3.0) { i.uv = v_uv0 * v_uvSizeOffset.xy + v_uvSizeOffset.zw; } else if (v_uvMode >= 2.0) { i.uv = fract(v_uv0) * v_uvSizeOffset.xy + v_uvSizeOffset.zw; } else if (v_uvMode >= 1.0) { i.uv = evalSlicedUV(v_uv0) * v_uvSizeOffset.xy + v_uvSizeOffset.zw; } else { i.uv = v_uv0; }

在 GLSL 中,循环变量必须是常量或者编译时已知,代码示例如下:

glslconst float value = 10.; for(float i = 0.0; i 缺省限定符,和 C 语言的值传递类似,指明传入的参数传递的是值,函数内不会修改传入的值inout类似于 C 语言的引用,参数的值会传入函数并返回函数内修改的值out参数的值不会传入函数,由函数内部修改并返回修改后的值精度限定符 ​

GLSL 引入了精度限定符,用于指定整型或浮点型变量的精度。精度限定符可使着色器的编写者明确定义着色器变量计算时使用的精度。在 在 Shader 头部声明的精度应用于整个 Shader,是所有基于浮点型的变量的默认精度,同时也可以定义单个变量的精度。在 Shader 中如果没有指定默认精度,则所有的整型和浮点型变量都采用高精度计算。

GLSL 支持的精度限定符包括以下几种:

限定符说明highp高精度。浮点型精度范围为 [-262, 262]整型精度范围为 [-216, 216]。mediump中精度。浮点型精度范围为 [-214, 214]整型精度范围为 [-210, 210]。lowp低精度。浮点型精度范围为 [-28, 28]整型精度范围为 [-28, 28]。

代码示例如下:

glslhighp mat4 cc_matWorld; mediump vec2 dir; lowp vec4 cc_shadowColor;预处理宏定义 ​

GLSL 允许定义和 C 语言类似的宏定义。

预处理宏定义允许着色器定义多样化的动态分支,确定最终的渲染效果。

在 GLSL 中使用预处理宏定义的代码示例如下:

glsl#define #undef #if #ifdef #ifndef #else #elif #endif

下方代码示例若 USE_VERTEX_COLOR 条件为真,则声明一个名为 v_color 的四维向量:

glsl#if USE_VERTEX_COLOR in vec4 v_color; #endif

预处理宏定义和引擎的交互部分可参考: 预处理宏定义

注意:在引擎中,材质的预处理宏定义在材质初始化完成后便不能修改。如果需要修改,请使用 Material.initialize 或 Material.reset 方法。代码示例可参考:程序化使用材质



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3